home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / LIBPNG / PNGRTRAN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-06  |  95.8 KB  |  2,857 lines  |  [TEXT/CWIE]

  1.  
  2. /* pngrtran.c - transforms the data in a row for png readers
  3.  
  4.    libpng 1.0 beta 4 - version 0.90
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    January 10, 1997
  8.    */
  9.  
  10. #define PNG_INTERNAL
  11. #include "png.h"
  12.  
  13. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  14. /* handle alpha and tRNS via a background color */
  15. void
  16. png_set_background(png_structp png_ptr,
  17.    png_color_16p background_color, int background_gamma_code,
  18.    int need_expand, double background_gamma)
  19. {
  20.    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
  21.    {
  22.       png_warning(png_ptr, "Application must supply a known background gamma");
  23.       return;
  24.    }
  25.  
  26.    png_ptr->transformations |= PNG_BACKGROUND;
  27.    png_memcpy(&(png_ptr->background), background_color,
  28.       sizeof(png_color_16));
  29.    png_ptr->background_gamma = (float)background_gamma;
  30.    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  31.    png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
  32. }
  33. #endif
  34.  
  35. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  36. /* strip 16 bit depth files to 8 bit depth */
  37. void
  38. png_set_strip_16(png_structp png_ptr)
  39. {
  40.    png_ptr->transformations |= PNG_16_TO_8;
  41. }
  42. #endif
  43.  
  44. #if defined(PNG_READ_DITHER_SUPPORTED)
  45. /* dither file to 8 bit.  Supply a palette, the current number
  46.    of elements in the palette, the maximum number of elements
  47.    allowed, and a histogram, if possible.  If the current number
  48.    is greater then the maximum number, the palette will be
  49.    modified to fit in the maximum number */
  50.  
  51.  
  52. typedef struct png_dsort_struct
  53. {
  54.    struct png_dsort_struct FAR * next;
  55.    png_byte left;
  56.    png_byte right;
  57. } png_dsort;
  58. typedef png_dsort FAR *       png_dsortp;
  59. typedef png_dsort FAR * FAR * png_dsortpp;
  60.  
  61. void
  62. png_set_dither(png_structp png_ptr, png_colorp palette,
  63.    int num_palette, int maximum_colors, png_uint_16p histogram,
  64.    int full_dither)
  65. {
  66.    png_ptr->transformations |= PNG_DITHER;
  67.  
  68.    if (!full_dither)
  69.    {
  70.       int i;
  71.  
  72.       png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
  73.          num_palette * sizeof (png_byte));
  74.       for (i = 0; i < num_palette; i++)
  75.          png_ptr->dither_index[i] = (png_byte)i;
  76.    }
  77.  
  78.    if (num_palette > maximum_colors)
  79.    {
  80.       if (histogram)
  81.       {
  82.          /* this is easy enough, just throw out the least used colors.
  83.             perhaps not the best solution, but good enough */
  84.  
  85.          int i;
  86.          png_bytep sort;
  87.  
  88.          /* initialize an array to sort colors */
  89.          sort = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte));
  90.  
  91.          /* initialize the sort array */
  92.          for (i = 0; i < num_palette; i++)
  93.             sort[i] = (png_byte)i;
  94.  
  95.          /* find the least used palette entries by starting a
  96.             bubble sort, and running it until we have sorted
  97.             out enough colors.  Note that we don't care about
  98.             sorting all the colors, just finding which are
  99.             least used. */
  100.  
  101.          for (i = num_palette - 1; i >= maximum_colors; i--)
  102.          {
  103.             int done; /* to stop early if the list is pre-sorted */
  104.             int j;
  105.  
  106.             done = 1;
  107.             for (j = 0; j < i; j++)
  108.             {
  109.                if (histogram[sort[j]] < histogram[sort[j + 1]])
  110.                {
  111.                   png_byte t;
  112.  
  113.                   t = sort[j];
  114.                   sort[j] = sort[j + 1];
  115.                   sort[j + 1] = t;
  116.                   done = 0;
  117.                }
  118.             }
  119.             if (done)
  120.                break;
  121.          }
  122.  
  123.          /* swap the palette around, and set up a table, if necessary */
  124.          if (full_dither)
  125.          {
  126.             int j;
  127.  
  128.             /* put all the useful colors within the max, but don't
  129.                move the others */
  130.             j = num_palette;
  131.             for (i = 0; i < maximum_colors; i++)
  132.             {
  133.                if (sort[i] >= maximum_colors)
  134.                {
  135.                   do
  136.                      j--;
  137.                   while (sort[j] >= maximum_colors);
  138.                   palette[i] = palette[j];
  139.                }
  140.             }
  141.          }
  142.          else
  143.          {
  144.             int j;
  145.  
  146.             /* move all the used colors inside the max limit, and
  147.                develop a translation table */
  148.             j = num_palette;
  149.             for (i = 0; i < maximum_colors; i++)
  150.             {
  151.                /* only move the colors we need to */
  152.                if (sort[i] >= maximum_colors)
  153.                {
  154.                   png_color tmp_color;
  155.  
  156.                   do
  157.                      j--;
  158.                   while (sort[j] >= maximum_colors);
  159.  
  160.                   tmp_color = palette[j];
  161.                   palette[j] = palette[i];
  162.                   palette[i] = tmp_color;
  163.                   /* indicate where the color went */
  164.                   png_ptr->dither_index[j] = (png_byte)i;
  165.                   png_ptr->dither_index[i] = (png_byte)j;
  166.                }
  167.             }
  168.             /* find closest color for those colors we are not
  169.                using */
  170.             for (i = 0; i < num_palette; i++)
  171.             {
  172.                if (png_ptr->dither_index[i] >= maximum_colors)
  173.                {
  174.                   int min_d, j, min_j, index;
  175.  
  176.                   /* find the closest color to one we threw out */
  177.                   index = png_ptr->dither_index[i];
  178.                   min_d = PNG_COLOR_DIST(palette[index],
  179.                         palette[0]);
  180.                   min_j = 0;
  181.                   for (j = 1; j < maximum_colors; j++)
  182.                   {
  183.                      int d;
  184.  
  185.                      d = PNG_COLOR_DIST(palette[index],
  186.                         palette[j]);
  187.  
  188.                      if (d < min_d)
  189.                      {
  190.                         min_d = d;
  191.                         min_j = j;
  192.                      }
  193.                   }
  194.                   /* point to closest color */
  195.                   png_ptr->dither_index[i] = (png_byte)min_j;
  196.                }
  197.             }
  198.          }
  199.          png_free(png_ptr, sort);
  200.       }
  201.       else
  202.       {
  203.          /* this is much harder to do simply (and quickly).  Perhaps
  204.             we need to go through a median cut routine, but those
  205.             don't always behave themselves with only a few colors
  206.             as input.  So we will just find the closest two colors,
  207.             and throw out one of them (chosen somewhat randomly).
  208.             */
  209.          int i;
  210.          int max_d;
  211.          int num_new_palette;
  212.          png_dsortpp hash;
  213.          png_bytep index_to_palette;
  214.             /* where the original index currently is in the palette */
  215.          png_bytep palette_to_index;
  216.             /* which original index points to this palette color */
  217.  
  218.          /* initialize palette index arrays */
  219.          index_to_palette = (png_bytep)png_malloc(png_ptr,
  220.             num_palette * sizeof (png_byte));
  221.          palette_to_index = (png_bytep)png_malloc(png_ptr,
  222.             num_palette * sizeof (png_byte));
  223.  
  224.          /* initialize the sort array */
  225.          for (i = 0; i < num_palette; i++)
  226.          {
  227.             index_to_palette[i] = (png_byte)i;
  228.             palette_to_index[i] = (png_byte)i;
  229.          }
  230.  
  231.          hash = (png_dsortpp)png_malloc(png_ptr, 769 * sizeof (png_dsortp));
  232.          for (i = 0; i < 769; i++)
  233.             hash[i] = (png_dsortp)0;
  234. /*         png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
  235.  
  236.          num_new_palette = num_palette;
  237.  
  238.          /* initial wild guess at how far apart the farthest pixel
  239.             pair we will be eliminating will be.  Larger
  240.             numbers mean more areas will be allocated, Smaller
  241.             numbers run the risk of not saving enough data, and
  242.             having to do this all over again.
  243.  
  244.             I have not done extensive checking on this number.
  245.             */
  246.          max_d = 96;
  247.  
  248.          while (num_new_palette > maximum_colors)
  249.          {
  250.             for (i = 0; i < num_new_palette - 1; i++)
  251.             {
  252.                int j;
  253.  
  254.                for (j = i + 1; j < num_new_palette; j++)
  255.                {
  256.                   int d;
  257.  
  258.                   d = PNG_COLOR_DIST(palette[i], palette[j]);
  259.  
  260.                   if (d <= max_d)
  261.                   {
  262.                      png_dsortp t;
  263.  
  264.                      t = png_malloc(png_ptr, sizeof (png_dsort));
  265.                      t->next = hash[d];
  266.                      t->left = (png_byte)i;
  267.                      t->right = (png_byte)j;
  268.                      hash[d] = t;
  269.                   }
  270.                }
  271.             }
  272.  
  273.             for (i = 0; i <= max_d; i++)
  274.             {
  275.                if (hash[i])
  276.                {
  277.                   png_dsortp p;
  278.  
  279.                   for (p = hash[i]; p; p = p->next)
  280.                   {
  281.                      if (index_to_palette[p->left] < num_new_palette &&
  282.                         index_to_palette[p->right] < num_new_palette)
  283.                      {
  284.                         int j, next_j;
  285.  
  286.                         if (num_new_palette & 1)
  287.                         {
  288.                            j = p->left;
  289.                            next_j = p->right;
  290.                         }
  291.                         else
  292.                         {
  293.                            j = p->right;
  294.                            next_j = p->left;
  295.                         }
  296.  
  297.                         num_new_palette--;
  298.                         palette[index_to_palette[j]] =
  299.                            palette[num_new_palette];
  300.                         if (!full_dither)
  301.                         {
  302.                            int k;
  303.  
  304.                            for (k = 0; k < num_palette; k++)
  305.                            {
  306.                               if (png_ptr->dither_index[k] ==
  307.                                  index_to_palette[j])
  308.                                  png_ptr->dither_index[k] =
  309.                                     index_to_palette[next_j];
  310.                               if (png_ptr->dither_index[k] ==
  311.                                  num_new_palette)
  312.                                  png_ptr->dither_index[k] =
  313.                                     index_to_palette[j];
  314.                            }
  315.                         }
  316.  
  317.                         index_to_palette[palette_to_index[num_new_palette]] =
  318.                            index_to_palette[j];
  319.                         palette_to_index[index_to_palette[j]] =
  320.                            palette_to_index[num_new_palette];
  321.  
  322.                         index_to_palette[j] = (png_byte)num_new_palette;
  323.                         palette_to_index[num_new_palette] = (png_byte)j;
  324.                      }
  325.                      if (num_new_palette <= maximum_colors)
  326.                         break;
  327.                   }
  328.                   if (num_new_palette <= maximum_colors)
  329.                      break;
  330.                }
  331.             }
  332.  
  333.             for (i = 0; i < 769; i++)
  334.             {
  335.                if (hash[i])
  336.                {
  337.                   png_dsortp p;
  338.  
  339.                   p = hash[i];
  340.                   while (p)
  341.                   {
  342.                      png_dsortp t;
  343.  
  344.                      t = p->next;
  345.                      png_free(png_ptr, p);
  346.                      p = t;
  347.                   }
  348.                }
  349.                hash[i] = 0;
  350.             }
  351.             max_d += 96;
  352.          }
  353.          png_free(png_ptr, hash);
  354.          png_free(png_ptr, palette_to_index);
  355.          png_free(png_ptr, index_to_palette);
  356.       }
  357.       num_palette = maximum_colors;
  358.    }
  359.    if (!(png_ptr->palette))
  360.    {
  361.       png_ptr->palette = palette;
  362.    }
  363.    png_ptr->num_palette = (png_uint_16)num_palette;
  364.  
  365.    if (full_dither)
  366.    {
  367.       int i;
  368.       int total_bits, num_red, num_green, num_blue;
  369.       png_uint_32 num_entries;
  370.       png_bytep distance;
  371.  
  372.       total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  373.          PNG_DITHER_BLUE_BITS;
  374.  
  375.       num_red = (1 << PNG_DITHER_RED_BITS);
  376.       num_green = (1 << PNG_DITHER_GREEN_BITS);
  377.       num_blue = (1 << PNG_DITHER_BLUE_BITS);
  378.       num_entries = ((png_uint_32)1 << total_bits);
  379.  
  380.       png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
  381.          (png_size_t)num_entries * sizeof (png_byte));
  382.  
  383.       png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte));
  384.  
  385.       distance = (png_bytep )png_malloc(png_ptr,
  386.          (png_size_t)num_entries * sizeof (png_byte));
  387.  
  388.       png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte));
  389.  
  390.       for (i = 0; i < num_palette; i++)
  391.       {
  392.          int r, g, b, ir, ig, ib;
  393.  
  394.          r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  395.          g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  396.          b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  397.  
  398.          for (ir = 0; ir < num_red; ir++)
  399.          {
  400.             int dr, index_r;
  401.  
  402.             dr = abs(ir - r);
  403.             index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  404.             for (ig = 0; ig < num_green; ig++)
  405.             {
  406.                int dg, dt, dm, index_g;
  407.  
  408.                dg = abs(ig - g);
  409.                dt = dr + dg;
  410.                dm = ((dr > dg) ? dr : dg);
  411.                index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  412.                for (ib = 0; ib < num_blue; ib++)
  413.                {
  414.                   int index, db, dmax, d;
  415.  
  416.                   index = index_g | ib;
  417.                   db = abs(ib - b);
  418.                   dmax = ((dm > db) ? dm : db);
  419.                   d = dmax + dt + db;
  420.  
  421.                   if (d < distance[index])
  422.                   {
  423.                      distance[index] = (png_byte)d;
  424.                      png_ptr->palette_lookup[index] = (png_byte)i;
  425.                   }
  426.                }
  427.             }
  428.          }
  429.       }
  430.  
  431.       png_free(png_ptr, distance);
  432.    }
  433. }
  434. #endif
  435.  
  436. #if defined(PNG_READ_GAMMA_SUPPORTED)
  437. /* Transform the image from the file_gamma to the screen_gamma.  We
  438.    only do transformations on images where the file_gamma and screen_gamma
  439.    are not close reciprocals, otherwise it slows things down slightly, and
  440.    also introduces small errors. */
  441. void
  442. png_set_gamma(png_structp png_ptr, double screen_gamma, double file_gamma)
  443. {
  444.    if (fabs(screen_gamma * file_gamma - 1.0) > 0.05)
  445.       png_ptr->transformations |= PNG_GAMMA;
  446.    png_ptr->gamma = (float)file_gamma;
  447.    png_ptr->display_gamma = (float)screen_gamma;
  448. }
  449. #endif
  450.  
  451. #if defined(PNG_READ_EXPAND_SUPPORTED)
  452. /* Expand paletted images to rgb, expand grayscale images of
  453.    less then 8 bit depth to 8 bit depth, and expand tRNS chunks
  454.    to alpha channels. */
  455. void
  456. png_set_expand(png_structp png_ptr)
  457. {
  458.    png_ptr->transformations |= PNG_EXPAND;
  459. }
  460. #endif
  461.  
  462. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  463. void
  464. png_set_gray_to_rgb(png_structp png_ptr)
  465. {
  466.    png_ptr->transformations |= PNG_GRAY_TO_RGB;
  467. }
  468. #endif
  469.  
  470. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  471. /* Convert a RGB image to a grayscale of the given width.  This would
  472.    allow us, for example, to convert a 24 bpp RGB image into an 8 or
  473.    16 bpp grayscale image. (Not yet implemented.) */
  474. void
  475. png_set_rgb_to_gray(png_structp png_ptr, int gray_bits)
  476. {
  477.    png_ptr->transformations |= PNG_RGB_TO_GRAY;
  478.    /* Need to do something with gray_bits here. */
  479. }
  480. #endif
  481.  
  482. /* initialize everything needed for the read.  This includes modifying
  483.    the palette */
  484. void
  485. png_init_read_transformations(png_structp png_ptr)
  486. {
  487.    int color_type;
  488.  
  489.    color_type = png_ptr->color_type;
  490.  
  491. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  492.    if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
  493.    {
  494.       if (color_type == PNG_COLOR_TYPE_GRAY)
  495.       {
  496.          /* expand background chunk. */
  497.          switch (png_ptr->bit_depth)
  498.          {
  499.             case 1:
  500.                png_ptr->background.gray *= (png_uint_16)0xff;
  501.                png_ptr->background.red = png_ptr->background.green =
  502.                png_ptr->background.blue = png_ptr->background.gray;
  503.                break;
  504.             case 2:
  505.                png_ptr->background.gray *= (png_uint_16)0x55;
  506.                png_ptr->background.red = png_ptr->background.green =
  507.                png_ptr->background.blue = png_ptr->background.gray;
  508.                break;
  509.             case 4:
  510.                png_ptr->background.gray *= (png_uint_16)0x11;
  511.                png_ptr->background.red = png_ptr->background.green =
  512.                png_ptr->background.blue = png_ptr->background.gray;
  513.                break;
  514.             case 8:
  515.             case 16:
  516.                png_ptr->background.red = png_ptr->background.green =
  517.                png_ptr->background.blue = png_ptr->background.gray;
  518.                break;
  519.          }
  520.       }
  521.       else if (color_type == PNG_COLOR_TYPE_PALETTE)
  522.       {
  523.          png_ptr->background.red   =
  524.             png_ptr->palette[png_ptr->background.index].red;
  525.          png_ptr->background.green =
  526.             png_ptr->palette[png_ptr->background.index].green;
  527.          png_ptr->background.blue  =
  528.             png_ptr->palette[png_ptr->background.index].blue;
  529.       }
  530.    }
  531. #endif
  532.  
  533. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  534.    png_ptr->background_1 = png_ptr->background;
  535. #endif
  536. #if defined(PNG_READ_GAMMA_SUPPORTED)
  537.    if (png_ptr->transformations & PNG_GAMMA)
  538.    {
  539.       png_build_gamma_table(png_ptr);
  540. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  541.       if (png_ptr->transformations & PNG_BACKGROUND)
  542.       {
  543.          if (color_type == PNG_COLOR_TYPE_PALETTE)
  544.          {
  545.             int num_palette, i;
  546.             png_color back, back_1;
  547.             png_colorp palette;
  548.  
  549.             palette = png_ptr->palette;
  550.             num_palette = png_ptr->num_palette;
  551.  
  552.             back.red = png_ptr->gamma_table[png_ptr->background.red];
  553.             back.green = png_ptr->gamma_table[png_ptr->background.green];
  554.             back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  555.  
  556.             back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  557.             back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  558.             back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  559.  
  560.             for (i = 0; i < num_palette; i++)
  561.             {
  562.                if (i < (int)png_ptr->num_trans)
  563.                {
  564.                   if (png_ptr->trans[i] == 0)
  565.                   {
  566.                      palette[i] = back;
  567.                   }
  568.                   else if (png_ptr->trans[i] != 0xff)
  569.                   {
  570.                      int v, w;
  571.  
  572.                      v = png_ptr->gamma_to_1[palette[i].red];
  573.                      w = (int)(((png_uint_32)(v) *
  574.                         (p_ptr->transformations & PNG_BACKGROUND &&
  575.        color_type == PNG_COLOR_TYPE_PALETTE)
  576.    {
  577.       int i;
  578.       png_color back;
  579.       png_colorp palette;
  580.  
  581.       palette = png_ptr->palette;
  582.       back.red   = (png_byte)png_ptr->background.red;
  583.       back.green = (png_byte)png_ptr->background.green;
  584.       back.blue  = (png_byte)png_ptr->background.blue;
  585.  
  586.       for (i = 0; i < png_ptr->num_trans; i++)
  587.       {
  588.          if (png_ptr->trans[i] == 0)
  589.          {
  590.             palette[i] = back;
  591.          }
  592.          else if (png_ptr->trans[i] != 0xff)
  593.          {
  594.             palette[i].red = (png_byte)((
  595.                (png_uint_32)(palette[i].red) *
  596.                (png_uint_32)(png_ptr->trans[i]) +
  597.                (png_uint_32)(back.red) *
  598.                (png_uint_32)(255 - png_ptr->trans[i]) +
  599.                127) / 255);
  600.             palette[i].green = (png_byte)((
  601.                (png_uint_32)(palette[i].green) *
  602.                (png_uint_32)(png_ptr->trans[i]) +
  603.                (png_uint_32)(back.green) *
  604.                (png_uint_32)(255 - png_ptr->trans[i]) +
  605.                127) / 255);
  606.             palette[i].blue = (png_byte)((
  607.                (png_uint_32)(palette[i].blue) *
  608.                (png_uint_32)(png_ptr->trans[i]) +
  609.                (png_uint_32)(back.blue) *
  610.                (png_uint_32)(255 - png_ptr->trans[i]) +
  611.                127) / 255);
  612.          }
  613.       }
  614.    }
  615. #endif
  616.  
  617. #if defined(PNG_READ_SHIFT_SUPPORTED)
  618.    if ((png_ptr->transformations & PNG_SHIFT) &&
  619.       color_type == PNG_COLOR_TYPE_PALETTE)
  620.    {
  621.       png_uint_16 i;
  622.       int sr, sg, sb;
  623.  
  624.       sr = 8 - png_ptr->sig_bit.red;
  625.       if (sr < 0 || sr > 8)
  626.          sr = 0;
  627.       sg = 8 - png_ptr->sig_bit.green;
  628.       if (sg < 0 || sg > 8)
  629.          sg = 0;
  630.       sb = 8 - png_ptr->sig_bit.blue;
  631.       if (sb < 0 || sb > 8)
  632.          sb = 0;
  633.       for (i = 0; i < png_ptr->num_palette; i++)
  634.       {
  635.          png_ptr->palette[i].red >>= sr;
  636.          png_ptr->palette[i].green >>= sg;
  637.          png_ptr->palette[i].blue >>= sb;
  638.       }
  639.    }
  640. #endif
  641. }
  642.  
  643. /* modify the info structure to reflect the transformations.  The
  644.    info should be updated so a png file could be written with it,
  645.    assuming the transformations result in valid png data */
  646. void
  647. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  648. {
  649. #if defined(PNG_READ_EXPAND_SUPPORTED)
  650.    if ((png_ptr->transformations & PNG_EXPAND) &&
  651.       info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  652.    {
  653.       if (png_ptr->num_trans)
  654.          info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  655.       else
  656.          info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  657.       info_ptr->bit_depth = 8;
  658.       info_ptr->num_trans = 0;
  659.    }
  660.    else if (png_ptr->transformations & PNG_EXPAND)
  661.    {
  662.       if (png_ptr->num_trans)
  663.          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  664.       if (info_ptr->bit_depth < 8)
  665.          info_ptr->bit_depth = 8;
  666.       info_ptr->num_trans = 0;
  667.    }
  668. #endif
  669.  
  670. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  671.    if (png_ptr->transformations & PNG_BACKGROUND)
  672.    {
  673.       info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  674.       info_ptr->num_trans = 0;
  675.       info_ptr->background = png_ptr->background;
  676.    }
  677. #endif
  678.  
  679. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  680.    if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
  681.       info_ptr->bit_depth = 8;
  682. #endif
  683.  
  684. #if defined(PNG_READ_DITHER_SUPPORTED)
  685.    if (png_ptr->transformations & PNG_DITHER)
  686.    {
  687.       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  688.          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  689.          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  690.       {
  691.          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  692.       }
  693.    }
  694. #endif
  695.  
  696. #if defined(PNG_READ_PACK_SUPPORTED)
  697.    if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
  698.       info_ptr->bit_depth = 8;
  699. #endif
  700.  
  701. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  702.    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  703.       !(info_ptr->color_type & PNG_COLOR_MASK_COLOR))
  704.       info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  705. #endif
  706.    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  707.       info_ptr->channels = 1;
  708.    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  709.       info_ptr->channels = 3;
  710.    else
  711.       info_ptr->channels = 1;
  712.    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  713.       info_ptr->channels++;
  714.    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  715.       info_ptr->bit_depth);
  716.    info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
  717. }
  718.  
  719. /* transform the row.  The order of transformations is significant,
  720.    and is very touchy.  If you add a transformation, take care to
  721.    decide how it fits in with the other transformations here */
  722. void
  723. png_do_read_transformations(png_structp png_ptr)
  724. {
  725.  
  726. #if defined(PNG_READ_EXPAND_SUPPORTED)
  727.    if ((png_ptr->transformations & PNG_EXPAND) &&
  728.       png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  729.    {
  730.       png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  731.          png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  732.    }
  733.    else if (png_ptr->transformations & PNG_EXPAND)
  734.    {
  735.       if (png_ptr->num_trans)
  736.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  737.             &(png_ptr->trans_values));
  738.       else
  739.          png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  740.             NULL);
  741.    }
  742. #endif
  743.  
  744. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  745.    if (png_ptr->transformations & PNG_BACKGROUND)
  746.       png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  747.          &(png_ptr->trans_values), &(png_ptr->background),
  748.          &(png_ptr->background_1),
  749.          png_ptr->gamma_table, png_ptr->gamma_from_1,
  750.          png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  751.          png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  752.          png_ptr->gamma_shift);
  753. #endif
  754.  
  755. #if defined(PNG_READ_GAMMA_SUPPORTED)
  756.    if ((png_ptr->transformations & PNG_GAMMA) &&
  757.       !(png_ptr->transformations & PNG_BACKGROUND) &&
  758.       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
  759.       png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  760.          png_ptr->gamma_table, png_ptr->gamma_16_table,
  761.          png_ptr->gamma_shift);
  762. #endif
  763.  
  764. #if defined(PNG_RGB_TO_GRAY_SUPPORTED)
  765.    if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  766.       png_do_rgb_to_gray(&(png_ptr->row_info), png_ptr->row_buf + 1);
  767. #endif
  768.  
  769. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  770.    if (png_ptr->transformations & PNG_16_TO_8)
  771.       png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  772. #endif
  773.  
  774. #if defined(PNG_READ_DITHER_SUPPORTED)
  775.    if (png_ptr->transformations & PNG_DITHER)
  776.    {
  777.       png_do_dither((png_row_infop)&(png_ptr->row_info), 
  778.          png_ptr->row_buf + 1,
  779.          png_ptr->palette_lookup,
  780.          png_ptr->dither_index);
  781.    }      
  782. #endif
  783.  
  784. #if defined(PNG_READ_INVERT_SUPPORTED)
  785.    if (png_ptr->transformations & PNG_INVERT_MONO)
  786.       png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  787. #endif
  788.  
  789. #if defined(PNG_READ_SHIFT_SUPPORTED)
  790.    if (png_ptr->transformations & PNG_SHIFT)
  791.       png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  792.          &(png_ptr->shift));
  793. #endif
  794.  
  795. #if defined(PNG_READ_PACK_SUPPORTED)
  796.    if (png_ptr->transformations & PNG_PACK)
  797.       png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  798. #endif
  799.  
  800. #if defined(PNG_READ_BGR_SUPPORTED)
  801.    if (png_ptr->transformations & PNG_BGR)
  802.       png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  803. #endif
  804.  
  805. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  806.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  807.       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  808. #endif
  809.  
  810. #if defined(PNG_READ_SWAP_SUPPORTED)
  811.    if (png_ptr->transformations & PNG_SWAP_BYTES)
  812.       png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  813. #endif
  814.  
  815. #if defined(PNG_READ_FILLER_SUPPORTED)
  816.    if (png_ptr->transformations & PNG_FILLER)
  817.       png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  818.          png_ptr->filler, png_ptr->flags);
  819. #endif
  820. }
  821.  
  822. #if defined(PNG_READ_PACK_SUPPORTED)
  823. /* unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  824.    without changing the actual values.  Thus, if you had a row with
  825.    a bit depth of 1, you would end up with bytes that only contained
  826.    the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  827.    png_do_shift() after this. */
  828. void
  829. png_do_unpack(png_row_infop row_info, png_bytep row)
  830. {
  831.    int shift;
  832.    png_bytep sp, dp;
  833.    png_uint_32 i;
  834.    
  835.    if (row && row_info && row_info->bit_depth < 8)
  836.    {
  837.       switch (row_info->bit_depth)
  838.       {
  839.          case 1:
  840.          {
  841.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  842.             dp = row + (png_size_t)row_info->width - 1;
  843.             shift = 7 - (int)((row_info->width + 7) & 7);
  844.             for (i = 0; i < row_info->width; i++)
  845.             {
  846.                *dp = (png_byte)((*sp >> shift) & 0x1);
  847.                if (shift == 7)
  848.                {
  849.                   shift = 0;
  850.                   sp--;
  851.                }
  852.                else
  853.                   shift++;
  854.  
  855.                dp--;
  856.             }
  857.             break;
  858.          }
  859.          case 2:
  860.          {
  861.  
  862.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  863.             dp = row + (png_size_t)row_info->width - 1;
  864.             shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  865.             for (i = 0; i < row_info->width; i++)
  866.             {
  867.                *dp = (png_byte)((*sp >> shift) & 0x3);
  868.                if (shift == 6)
  869.                {
  870.                   shift = 0;
  871.                   sp--;
  872.                }
  873.                else
  874.                   shift += 2;
  875.  
  876.                dp--;
  877.             }
  878.             break;
  879.          }
  880.          case 4:
  881.          {
  882.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  883.             dp = row + (png_size_t)row_info->width - 1;
  884.             shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  885.             for (i = 0; i < row_info->width; i++)
  886.             {
  887.                *dp = (png_byte)((*sp >> shift) & 0xf);
  888.                if (shift == 4)
  889.                {
  890.                   shift = 0;
  891.                   sp--;
  892.                }
  893.                else
  894.                   shift = 4;
  895.  
  896.                dp--;
  897.             }
  898.             break;
  899.          }
  900.       }
  901.       row_info->bit_depth = 8;
  902.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  903.       row_info->rowbytes = row_info->width * row_info->channels;
  904.    }
  905. }
  906. #endif
  907.  
  908. #if defined(PNG_READ_SHIFT_SUPPORTED)
  909. /* reverse the effects of png_do_shift.  This routine merely shifts the
  910.    pixels back to their significant bits values.  Thus, if you have
  911.    a row of bit depth 8, but only 5 are significant, this will shift
  912.    the values back to 0 through 31 */
  913. void
  914. png_do_unshift(png_row_infop row_info, png_bytep row,
  915.    png_color_8p sig_bits)
  916. {
  917.    png_bytep bp;
  918.    png_uint_16 value;
  919.    png_uint_32 i;
  920.    if (row && row_info && sig_bits &&
  921.       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  922.    {
  923.       int shift[4];
  924.       int channels;
  925.  
  926.       channels = 0;
  927.       if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  928.       {
  929.          shift[channels++] = row_info->bit_depth - sig_bits->red;
  930.          shift[channels++] = row_info->bit_depth - sig_bits->green;
  931.          shift[channels++] = row_info->bit_depth - sig_bits->blue;
  932.       }
  933.       else
  934.       {
  935.          shift[channels++] = row_info->bit_depth - sig_bits->gray;
  936.       }
  937.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  938.       {
  939.          shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  940.       }
  941.  
  942.       value = 0;
  943.  
  944.       for (i = 0; i < channels; i++)
  945.       {
  946.          if (shift[(png_size_t)i] <= 0)
  947.             shift[(png_size_t)i] = 0;
  948.          else
  949.             value = 1;
  950.       }
  951.  
  952.       if (!value)
  953.          return;
  954.  
  955.       switch (row_info->bit_depth)
  956.       {
  957.          case 2:
  958.          {
  959.             for (bp = row, i = 0;
  960.                i < row_info->rowbytes;
  961.                i++, bp++)
  962.             {
  963.                *bp >>= 1;
  964.                *bp &= 0x55;
  965.             }
  966.             break;
  967.          }
  968.          case 4:
  969.          {
  970.             png_byte  mask;
  971.             mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
  972.                (png_byte)((int)0xf >> shift[0]);
  973.             for (bp = row, i = 0;
  974.                i < row_info->rowbytes;
  975.                i++, bp++)
  976.             {
  977.                *bp >>= shift[0];
  978.                *bp &= mask;
  979.             }
  980.             break;
  981.          }
  982.          case 8:
  983.          {
  984.             for (bp = row, i = 0;
  985.                i < row_info->width; i++)
  986.             {
  987.                int c;
  988.  
  989.                for (c = 0; c < row_info->channels; c++, bp++)
  990.                {
  991.                   *bp >>= shift[c];
  992.                }
  993.             }
  994.             break;
  995.          }
  996.          case 16:
  997.          {
  998.             for (bp = row, i = 0;
  999.                i < row_info->width; i++)
  1000.             {
  1001.                int c;
  1002.  
  1003.                for (c = 0; c < row_info->channels; c++, bp += 2)
  1004.                {
  1005.                   value = (png_uint_16)((*bp << 8) + *(bp + 1));
  1006.                   value >>= shift[c];
  1007.                   *bp = (png_byte)(value >> 8);
  1008.                   *(bp + 1) = (png_byte)(value & 0xff);
  1009.                }
  1010.             }
  1011.             break;
  1012.          }
  1013.       }
  1014.    }
  1015. }
  1016. #endif
  1017.  
  1018. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1019. /* chop rows of bit depth 16 down to 8 */
  1020. void
  1021. png_do_chop(png_row_infop row_info, png_bytep row)
  1022. {
  1023.    png_bytep sp, dp;
  1024.    png_uint_32 i;
  1025.  
  1026.    if (row && row_info && row_info->bit_depth == 16)
  1027.    {
  1028.       sp = row;
  1029.       dp = row;
  1030.       for (i = 0; i < row_info->width * row_info->channels; i++)
  1031.       {
  1032.          *dp = *sp;
  1033. /* not yet, as I'm afraid of overflow here
  1034.          *dp = ((((((png_uint_16)(*sp) << 8)) |
  1035.             (png_uint_16)((*(sp + 1) - *sp) & 0xff) +
  1036.             0x7f) >> 8) & 0xff);
  1037. */
  1038.          sp += 2;
  1039.          dp++;
  1040.       }
  1041.       row_info->bit_depth = 8;
  1042.       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1043.       row_info->rowbytes = row_info->width * row_info->channels;
  1044.    }
  1045. }
  1046. #endif
  1047.  
  1048. #if defined(PNG_READ_FILLER_SUPPORTED)
  1049. /* add filler byte */
  1050. void
  1051. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1052.    png_byte filler, png_uint_32 flags)
  1053. {
  1054.    png_bytep sp, dp;
  1055.    png_uint_32 i;
  1056.    if (row && row_info && row_info->color_type == 2 &&
  1057.       row_info->bit_depth == 8)
  1058.    {
  1059.       if (flags & PNG_FLAG_FILLER_AFTER)
  1060.       {
  1061.          for (i = 1, sp = row + (png_size_t)row_info->width * 3,
  1062.             dp = row + (png_size_t)row_info->width * 4;
  1063.             i < row_info->width;
  1064.             i++)
  1065.          {
  1066.             *(--dp) = filler;
  1067.             *(--dp) = *(--sp);
  1068.             *(--dp) = *(--sp);
  1069.             *(--dp) = *(--sp);
  1070.          }
  1071.          *(--dp) = filler;
  1072.          row_info->channels = 4;
  1073.          row_info->pixel_depth = 32;
  1074.          row_info->rowbytes = row_info->width * 4;
  1075.       }
  1076.       else
  1077.       {
  1078.          for (i = 0, sp = row + (png_size_t)row_info->width * 3,
  1079.             dp = row + (png_size_t)row_info->width * 4;
  1080.             i < row_info->width;
  1081.             i++)
  1082.          {
  1083.             *(--dp) = *(--sp);
  1084.             *(--dp) = *(--sp);
  1085.             *(--dp) = *(--sp);
  1086.             *(--dp) = filler;
  1087.          }
  1088.          row_info->channels = 4;
  1089.          row_info->pixel_depth = 32;
  1090.          row_info->rowbytes = row_info->width * 4;
  1091.       }
  1092.    }
  1093. }
  1094. #endif
  1095.  
  1096. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1097. /* expand grayscale files to rgb, with or without alpha */
  1098. void
  1099. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1100. {
  1101.    png_bytep sp, dp;
  1102.    png_uint_32 i;
  1103.  
  1104.    if (row && row_info && row_info->bit_depth >= 8 &&
  1105.       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1106.    {
  1107.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1108.       {
  1109.          if (row_info->bit_depth == 8)
  1110.          {
  1111.             for (i = 0, sp = row + (png_size_t)row_info->width - 1,
  1112.                dp = row + (png_size_t)row_info->width * 3 - 1;
  1113.                i < row_info->width;
  1114.                i++)
  1115.             {
  1116.                *(dp--) = *sp;
  1117.                *(dp--) = *sp;
  1118.                *(dp--) = *sp;
  1119.                sp--;
  1120.             }
  1121.          }
  1122.          else
  1123.          {
  1124.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1125.                dp = row + (png_size_t)row_info->width * 6 - 1;
  1126.                i < row_info->width;
  1127.                i++)
  1128.             {
  1129.                *(dp--) = *sp;
  1130.                *(dp--) = *(sp - 1);
  1131.                *(dp--) = *sp;
  1132.                *(dp--) = *(sp - 1);
  1133.                *(dp--) = *sp;
  1134.                *(dp--) = *(sp - 1);
  1135.                sp--;
  1136.                sp--;
  1137.             }
  1138.          }
  1139.       }
  1140.       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1141.       {
  1142.          if (row_info->bit_depth == 8)
  1143.          {
  1144.             for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
  1145.                dp = row + (png_size_t)row_info->width * 4 - 1;
  1146.                i < row_info->width;
  1147.                i++)
  1148.             {
  1149.                *(dp--) = *(sp--);
  1150.                *(dp--) = *sp;
  1151.                *(dp--) = *sp;
  1152.                *(dp--) = *sp;
  1153.                sp--;
  1154.             }
  1155.          }
  1156.          else
  1157.          {
  1158.             for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1,
  1159.                dp = row + (png_size_t)row_info->width * 8 - 1;
  1160.                i < row_info->width;
  1161.                i++)
  1162.             {
  1163.                *(dp--) = *(sp--);
  1164.                *(dp--) = *(sp--);
  1165.                *(dp--) = *sp;
  1166.                *(dp--) = *(sp - 1);
  1167.                *(dp--) = *sp;
  1168.                *(dp--) = *(sp - 1);
  1169.                *(dp--) = *sp;
  1170.                *(dp--) = *(sp - 1);
  1171.                sp--;
  1172.                sp--;
  1173.             }
  1174.          }
  1175.       }
  1176.       row_info->channels += (png_byte)2;
  1177.       row_info->color_type |= PNG_COLOR_MASK_COLOR;
  1178.       row_info->pixel_depth = (png_byte)(row_info->channels *
  1179.          row_info->bit_depth);
  1180.       row_info->rowbytes = ((row_info->width *
  1181.          row_info->pixel_depth + 7) >> 3);
  1182.    }
  1183. }
  1184. #endif
  1185.  
  1186. /* build a grayscale palette.  Palette is assumed to be 1 << bit_depth
  1187.    large of png_color.  This lets grayscale images be treated as
  1188.    paletted.  Most useful for gamma correction and simplification
  1189.    of code. */
  1190. void
  1191. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  1192. {
  1193.    int num_palette;
  1194.    int color_inc;
  1195.    int i;
  1196.    int v;
  1197.  
  1198.    if (!palette)
  1199.       return;
  1200.  
  1201.    switch (bit_depth)
  1202.    {
  1203.       case 1:
  1204.          num_palette = 2;
  1205.          color_inc = 0xff;
  1206.          break;
  1207.       case 2:
  1208.          num_palette = 4;
  1209.          color_inc = 0x55;
  1210.          break;
  1211.       case 4:
  1212.          num_palette = 16;
  1213.          color_inc = 0x11;
  1214.          break;
  1215.       case 8:
  1216.          num_palette = 256;
  1217.          color_inc = 1;
  1218.          break;
  1219.       default:
  1220.          num_palette = 0;
  1221.          color_inc = 0;
  1222.          break;
  1223.    }
  1224.  
  1225.    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  1226.    {
  1227.       palette[i].red = (png_byte)v;
  1228.       palette[i].green = (png_byte)v;
  1229.       palette[i].blue = (png_byte)v;
  1230.    }
  1231. }
  1232.  
  1233. /* This function is currently unused.  Do we really need it? */
  1234. #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
  1235. void
  1236. png_correct_palette(png_structp png_ptr, png_colorp palette,
  1237.    int num_palette)
  1238. {
  1239. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  1240.    if ((png_ptr->transformations & (PNG_GAMMA)) &&
  1241.       (png_ptr->transformations & (PNG_BACKGROUND)))
  1242.    {
  1243.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1244.       {
  1245.          int i;
  1246.          png_color back, back_1;
  1247.  
  1248.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1249.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1250.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1251.  
  1252.          back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  1253.          back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  1254.          back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  1255.  
  1256.          for (i = 0; i < num_palette; i++)
  1257.          {
  1258.             if (i < (int)png_ptr->num_trans &&
  1259.                png_ptr->trans[i] == 0)
  1260.             {
  1261.                palette[i] = back;
  1262.             }
  1263.             else if (i < (int)png_ptr->num_trans &&
  1264.                png_ptr->trans[i] != 0xff)
  1265.             {
  1266.                int v;
  1267.  
  1268.                v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  1269.                v = (int)(((png_uint_32)(v) *
  1270.                   (png_uint_32)(png_ptr->trans[i]) +
  1271.                   (png_uint_32)(back_1.red) *
  1272.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1273.                   127) / 255);
  1274.                palette[i].red = png_ptr->gamma_from_1[v];
  1275.  
  1276.                v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  1277.                v = (int)(((png_uint_32)(v) *
  1278.                   (png_uint_32)(png_ptr->trans[i]) +
  1279.                   (png_uint_32)(back_1.green) *
  1280.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1281.                   127) / 255);
  1282.                palette[i].green = png_ptr->gamma_from_1[v];
  1283.  
  1284.                v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  1285.                v = (int)(((png_uint_32)(v) *
  1286.                   (png_uint_32)(png_ptr->trans[i]) +
  1287.                   (png_uint_32)(back_1.blue) *
  1288.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1289.                   127) / 255);
  1290.                palette[i].blue = png_ptr->gamma_from_1[v];
  1291.             }
  1292.             else
  1293.             {
  1294.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1295.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1296.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1297.             }
  1298.          }
  1299.       }
  1300.       else
  1301.       {
  1302.          int i;
  1303.          png_color back;
  1304.  
  1305.          back.red = png_ptr->gamma_table[png_ptr->background.red];
  1306.          back.green = png_ptr->gamma_table[png_ptr->background.green];
  1307.          back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  1308.  
  1309.          for (i = 0; i < num_palette; i++)
  1310.          {
  1311.             if (palette[i].red == png_ptr->trans_values.gray)
  1312.             {
  1313.                palette[i] = back;
  1314.             }
  1315.             else
  1316.             {
  1317.                palette[i].red = png_ptr->gamma_table[palette[i].red];
  1318.                palette[i].green = png_ptr->gamma_table[palette[i].green];
  1319.                palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1320.             }
  1321.          }
  1322.       }
  1323.    }
  1324.    else
  1325. #endif
  1326. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1327.    if (png_ptr->transformations & (PNG_GAMMA))
  1328.    {
  1329.       int i;
  1330.  
  1331.       for (i = 0; i < num_palette; i++)
  1332.       {
  1333.          palette[i].red = png_ptr->gamma_table[palette[i].red];
  1334.          palette[i].green = png_ptr->gamma_table[palette[i].green];
  1335.          palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  1336.       }
  1337.    }
  1338. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1339.    else
  1340. #endif
  1341. #endif
  1342. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1343.    if (png_ptr->transformations & (PNG_BACKGROUND))
  1344.    {
  1345.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1346.       {
  1347.          int i;
  1348.          png_color back;
  1349.  
  1350.          back.red   = (png_byte)png_ptr->background.red;
  1351.          back.green = (png_byte)png_ptr->background.green;
  1352.          back.blue  = (png_byte)png_ptr->background.blue;
  1353.  
  1354.          for (i = 0; i < num_palette; i++)
  1355.          {
  1356.             if (i >= (int)png_ptr->num_trans ||
  1357.                png_ptr->trans[i] == 0)
  1358.             {
  1359.                palette[i].red = back.red;
  1360.                palette[i].green = back.green;
  1361.                palette[i].blue = back.blue;
  1362.             }
  1363.             else if (i < (int)png_ptr->num_trans ||
  1364.                png_ptr->trans[i] != 0xff)
  1365.             {
  1366.                palette[i].red = (png_byte)((
  1367.                   (png_uint_32)(png_ptr->palette[i].red) *
  1368.                   (png_uint_32)(png_ptr->trans[i]) +
  1369.                   (png_uint_32)(back.red) *
  1370.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1371.                   127) / 255);
  1372.                palette[i].green = (png_byte)((
  1373.                   (png_uint_32)(png_ptr->palette[i].green) *
  1374.                   (png_uint_32)(png_ptr->trans[i]) +
  1375.                   (png_uint_32)(back.green) *
  1376.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1377.                   127) / 255);
  1378.                palette[i].blue = (png_byte)((
  1379.                   (png_uint_32)(png_ptr->palette[i].blue) *
  1380.                   (png_uint_32)(png_ptr->trans[i]) +
  1381.                   (png_uint_32)(back.blue) *
  1382.                   (png_uint_32)(255 - png_ptr->trans[i]) +
  1383.                   127) / 255);
  1384.             }
  1385.          }
  1386.       }
  1387.       else /* assume grayscale palette (what else could it be?) */
  1388.       {
  1389.          int i;
  1390.  
  1391.          for (i = 0; i < num_palette; i++)
  1392.          {
  1393.             if (i == (int)png_ptr->trans_values.gray)
  1394.             {
  1395.                palette[i].red = (png_byte)png_ptr->background.red;
  1396.                palette[i].green = (png_byte)png_ptr->background.green;
  1397.                palette[i].blue = (png_byte)png_ptr->background.blue;
  1398.             }
  1399.          }
  1400.       }
  1401.    }
  1402. #endif
  1403. }
  1404. #endif
  1405.  
  1406. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1407. /* replace any alpha or transparency with the supplied background color.
  1408.    background is the color.  note that paletted files are taken care of
  1409.    elsewhere */
  1410. void
  1411. png_do_background(png_row_infop row_info, png_bytep row,
  1412.    png_color_16p trans_values, png_color_16p background,
  1413.    png_color_16p background_1,
  1414.    png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  1415.    png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  1416.    png_uint_16pp gamma_16_to_1, int gamma_shift)
  1417. {
  1418.    png_bytep sp, dp;
  1419.    png_uint_32 i;
  1420.    int shift;
  1421.  
  1422.    if (row && row_info && background &&
  1423.       (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  1424.       (row_info->color_type != PNG_COLOR_TYPE_PALETTE &&
  1425.       trans_values)))
  1426.    {
  1427.       switch (row_info->color_type)
  1428.       {
  1429.          case PNG_COLOR_TYPE_GRAY:
  1430.          {
  1431.             switch (row_info->bit_depth)
  1432.             {
  1433.                case 1:
  1434.                {
  1435.                   sp = row;
  1436.                   shift = 7;
  1437.                   for (i = 0; i < row_info->width; i++)
  1438.                   {
  1439.                      if (((*sp >> shift) & 0x1) ==
  1440.                         trans_values->gray)
  1441.                      {
  1442.                         *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  1443.                         *sp |= (png_byte)(background->gray << shift);
  1444.                      }
  1445.                      if (!shift)
  1446.                      {
  1447.                         shift = 7;
  1448.                         sp++;
  1449.                      }
  1450.                      else
  1451.                         shift--;
  1452.                   }
  1453.                   break;
  1454.                }
  1455.                case 2:
  1456.                {
  1457.                   sp = row;
  1458.                   shift = 6;
  1459.                   for (i = 0; i < row_info->width; i++)
  1460.                   {
  1461.                      if (((*sp >> shift) & 0x3) ==
  1462.                         trans_values->gray)
  1463.                      {
  1464.                         *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  1465.                         *sp |= (png_byte)(background->gray << shift);
  1466.                      }
  1467.                      if (!shift)
  1468.                      {
  1469.                         shift = 6;
  1470.                         sp++;
  1471.                      }
  1472.                      else
  1473.                         shift -= 2;
  1474.                   }
  1475.                   break;
  1476.                }
  1477.                case 4:
  1478.                {
  1479.                   sp = row;
  1480.                   shift = 4;
  1481.                   for (i = 0; i < row_info->width; i++)
  1482.                   {
  1483.                      if (((*sp >> shift) & 0xf) ==
  1484.                         trans_values->gray)
  1485.                      {
  1486.                         *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  1487.                         *sp |= (png_byte)(background->gray << shift);
  1488.                      }
  1489.                      if (!shift)
  1490.                      {
  1491.                         shift = 4;
  1492.                         sp++;
  1493.                      }
  1494.                      else
  1495.                         shift -= 4;
  1496.                   }
  1497.                   break;
  1498.                }
  1499.                case 8:
  1500.                {
  1501. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1502.                   if (gamma_table)
  1503.                   {
  1504.  
  1505.                      for (i = 0, sp = row;
  1506.                         i < row_info->width; i++, sp++)
  1507.                      {
  1508.                         if (*sp == trans_values->gray)
  1509.                         {
  1510.                            *sp = background->gray;
  1511.                         }
  1512.                         else
  1513.                         {
  1514.                            *sp = gamma_table[*sp];
  1515.                         }
  1516.                      }
  1517.                   }
  1518.                   else
  1519. #endif
  1520.                   {
  1521.                      for (i = 0, sp = row;
  1522.                         i < row_info->width; i++, sp++)
  1523.                      {
  1524.                         if (*sp == trans_values->gray)
  1525.                         {
  1526.                            *sp = background->gray;
  1527.                         }
  1528.                      }
  1529.                   }
  1530.                   break;
  1531.                }
  1532.                case 16:
  1533.                {
  1534. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1535.                   if (gamma_16)
  1536.                   {
  1537.                      for (i = 0, sp = row;
  1538.                         i < row_info->width; i++, sp += 2)
  1539.                      {
  1540.                         png_uint_16 v;
  1541.  
  1542.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1543.                            (png_uint_16)(*(sp + 1)));
  1544.                         if (v == trans_values->gray)
  1545.                         {
  1546.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1547.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1548.                         }
  1549.                         else
  1550.                         {
  1551.                            v = gamma_16[
  1552.                               *(sp + 1) >> gamma_shift][*sp];
  1553.                            *sp = (png_byte)((v >> 8) & 0xff);
  1554.                            *(sp + 1) = (png_byte)(v & 0xff);
  1555.                         }
  1556.                      }
  1557.                   }
  1558.                   else
  1559. #endif
  1560.                   {
  1561.                      for (i = 0, sp = row;
  1562.                         i < row_info->width; i++, sp += 2)
  1563.                      {
  1564.                         png_uint_16 v;
  1565.  
  1566.                         v = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1567.                            (png_uint_16)(*(sp + 1)));
  1568.                         if (v == trans_values->gray)
  1569.                         {
  1570.                            *sp = (png_byte)((background->gray >> 8) & 0xff);
  1571.                            *(sp + 1) = (png_byte)(background->gray & 0xff);
  1572.                         }
  1573.                      }
  1574.                   }
  1575.                   break;
  1576.                }
  1577.             }
  1578.             break;
  1579.          }
  1580.          case PNG_COLOR_TYPE_RGB:
  1581.          {
  1582.             if (row_info->bit_depth == 8)
  1583.             {
  1584. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1585.                if (gamma_table)
  1586.                {
  1587.                   for (i = 0, sp = row;
  1588.                      i < row_info->width; i++, sp += 3)
  1589.                   {
  1590.                      if (*sp == trans_values->red &&
  1591.                         *(sp + 1) == trans_values->green &&
  1592.                         *(sp + 2) == trans_values->blue)
  1593.                      {
  1594.                         *sp = background->red;
  1595.                         *(sp + 1) = background->green;
  1596.                         *(sp + 2) = background->blue;
  1597.                      }
  1598.                      else
  1599.                      {
  1600.                         *sp = gamma_table[*sp];
  1601.                         *(sp + 1) = gamma_table[*(sp + 1)];
  1602.                         *(sp + 2) = gamma_table[*(sp + 2)];
  1603.                      }
  1604.                   }
  1605.                }
  1606.                else
  1607. #endif
  1608.                {
  1609.                   for (i = 0, sp = row;
  1610.                      i < row_info->width; i++, sp += 3)
  1611.                   {
  1612.                      if (*sp == trans_values->red &&
  1613.                         *(sp + 1) == trans_values->green &&
  1614.                         *(sp + 2) == trans_values->blue)
  1615.                      {
  1616.                         *sp = background->red;
  1617.                         *(sp + 1) = background->green;
  1618.                         *(sp + 2) = background->blue;
  1619.                      }
  1620.                   }
  1621.                }
  1622.             }
  1623.             else if (row_info->bit_depth == 16)
  1624.             {
  1625. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1626.                if (gamma_16)
  1627.                {
  1628.                   for (i = 0, sp = row;
  1629.                      i < row_info->width; i++, sp += 6)
  1630.                   {
  1631.                      png_uint_16 r, g, b;
  1632.  
  1633.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1634.                         (png_uint_16)(*(sp + 1)));
  1635.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1636.                         (png_uint_16)(*(sp + 3)));
  1637.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1638.                         (png_uint_16)(*(sp + 5)));
  1639.                      if (r == trans_values->red &&
  1640.                         g == trans_values->green &&
  1641.                         b == trans_values->blue)
  1642.                      {
  1643.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1644.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1645.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1646.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1647.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1648.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1649.                      }
  1650.                      else
  1651.                      {
  1652.                         png_uint_16 v;
  1653.                         v = gamma_16[
  1654.                            *(sp + 1) >> gamma_shift][*sp];
  1655.                         *sp = (png_byte)((v >> 8) & 0xff);
  1656.                         *(sp + 1) = (png_byte)(v & 0xff);
  1657.                         v = gamma_16[
  1658.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1659.                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  1660.                         *(sp + 3) = (png_byte)(v & 0xff);
  1661.                         v = gamma_16[
  1662.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1663.                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  1664.                         *(sp + 5) = (png_byte)(v & 0xff);
  1665.                      }
  1666.                   }
  1667.                }
  1668.                else
  1669. #endif
  1670.                {
  1671.                   for (i = 0, sp = row;
  1672.                      i < row_info->width; i++, sp += 6)
  1673.                   {
  1674.                      png_uint_16 r, g, b;
  1675.  
  1676.                      r = (png_uint_16)(((png_uint_16)(*sp) << 8) +
  1677.                         (png_uint_16)(*(sp + 1)));
  1678.                      g = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1679.                         (png_uint_16)(*(sp + 3)));
  1680.                      b = (png_uint_16)(((png_uint_16)(*(sp + 4)) << 8) +
  1681.                         (png_uint_16)(*(sp + 5)));
  1682.                      if (r == trans_values->red &&
  1683.                         g == trans_values->green &&
  1684.                         b == trans_values->blue)
  1685.                      {
  1686.                         *sp = (png_byte)((background->red >> 8) & 0xff);
  1687.                         *(sp + 1) = (png_byte)(background->red & 0xff);
  1688.                         *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1689.                         *(sp + 3) = (png_byte)(background->green & 0xff);
  1690.                         *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1691.                         *(sp + 5) = (png_byte)(background->blue & 0xff);
  1692.                      }
  1693.                   }
  1694.                }
  1695.             }
  1696.             break;
  1697.          }
  1698.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  1699.          {
  1700.             switch (row_info->bit_depth)
  1701.             {
  1702.                case 8:
  1703.                {
  1704. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1705.                   if (gamma_to_1 && gamma_from_1 && gamma_table)
  1706.                   {
  1707.                      for (i = 0, sp = row,
  1708.                         dp = row;
  1709.                         i < row_info->width; i++, sp += 2, dp++)
  1710.                      {
  1711.                         png_uint_16 a;
  1712.  
  1713.                         a = *(sp + 1);
  1714.                         if (a == 0xff)
  1715.                         {
  1716.                            *dp = gamma_table[*sp];
  1717.                         }
  1718.                         else if (a == 0)
  1719.                         {
  1720.                            *dp = background->gray;
  1721.                         }
  1722.                         else
  1723.                         {
  1724.                            png_uint_16 v;
  1725.  
  1726.                            v = gamma_to_1[*sp];
  1727.                            v = (png_uint_16)(((png_uint_16)(v) * a +
  1728.                               (png_uint_16)background_1->gray *
  1729.                               (255 - a) + 127) / 255);
  1730.                            *dp = gamma_from_1[v];
  1731.                         }
  1732.                      }
  1733.                   }
  1734.                   else
  1735. #endif
  1736.                   {
  1737.                      for (i = 0, sp = row,
  1738.                         dp = row;
  1739.                         i < row_info->width; i++, sp += 2, dp++)
  1740.                      {
  1741.                         png_uint_16 a;
  1742.  
  1743.                         a = *(sp + 1);
  1744.                         if (a == 0xff)
  1745.                         {
  1746.                            *dp = *sp;
  1747.                         }
  1748.                         else if (a == 0)
  1749.                         {
  1750.                            *dp = background->gray;
  1751.                         }
  1752.                         else
  1753.                         {
  1754.                            *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1755.                               (png_uint_16)background_1->gray *
  1756.                               (255 - a) + 127) / 255);
  1757.                         }
  1758.                      }
  1759.                   }
  1760.                   break;
  1761.                }
  1762.                case 16:
  1763.                {
  1764. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1765.                   if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  1766.                   {
  1767.                      for (i = 0, sp = row,
  1768.                         dp = row;
  1769.                         i < row_info->width; i++, sp += 4, dp += 2)
  1770.                      {
  1771.                         png_uint_16 a;
  1772.  
  1773.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1774.                            (png_uint_16)(*(sp + 3)));
  1775.                         if (a == (png_uint_16)0xffff)
  1776.                         {
  1777.                            png_uint_32 v;
  1778.  
  1779.                            v = gamma_16[
  1780.                               *(sp + 1) >> gamma_shift][*sp];
  1781.                            *dp = (png_byte)((v >> 8) & 0xff);
  1782.                            *(dp + 1) = (png_byte)(v & 0xff);
  1783.                         }
  1784.                         else if (a == 0)
  1785.                         {
  1786.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1787.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1788.                         }
  1789.                         else
  1790.                         {
  1791.                            png_uint_32 g, v;
  1792.  
  1793.                            g = gamma_16_to_1[
  1794.                               *(sp + 1) >> gamma_shift][*sp];
  1795.                            v = (g * (png_uint_32)a +
  1796.                               (png_uint_32)background_1->gray *
  1797.                               (png_uint_32)((png_uint_16)65535L - a) +
  1798.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1799.                            v = gamma_16_from_1[(size_t)(
  1800.                               (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1801.                            *dp = (png_byte)((v >> 8) & 0xff);
  1802.                            *(dp + 1) = (png_byte)(v & 0xff);
  1803.                         }
  1804.                      }
  1805.                   }
  1806.                   else
  1807. #endif
  1808.                   {
  1809.                      for (i = 0, sp = row,
  1810.                         dp = row;
  1811.                         i < row_info->width; i++, sp += 4, dp += 2)
  1812.                      {
  1813.                         png_uint_16 a;
  1814.  
  1815.                         a = (png_uint_16)(((png_uint_16)(*(sp + 2)) << 8) +
  1816.                            (png_uint_16)(*(sp + 3)));
  1817.                         if (a == (png_uint_16)0xffff)
  1818.                         {
  1819.                            png_memcpy(dp, sp, 2);
  1820.                         }
  1821.                         else if (a == 0)
  1822.                         {
  1823.                            *dp = (png_byte)((background->gray >> 8) & 0xff);
  1824.                            *(dp + 1) = (png_byte)(background->gray & 0xff);
  1825.                         }
  1826.                         else
  1827.                         {
  1828.                            png_uint_32 g, v;
  1829.  
  1830.                            g = ((png_uint_32)(*sp) << 8) +
  1831.                               (png_uint_32)(*(sp + 1));
  1832.                            v = (g * (png_uint_32)a +
  1833.                               (png_uint_32)background_1->gray *
  1834.                               (png_uint_32)((png_uint_16)65535L - a) +
  1835.                               (png_uint_16)32767) / (png_uint_16)65535L;
  1836.                            *dp = (png_byte)((v >> 8) & 0xff);
  1837.                            *(dp + 1) = (png_byte)(v & 0xff);
  1838.                         }
  1839.                      }
  1840.                   }
  1841.                   break;
  1842.                }
  1843.             }
  1844.             break;
  1845.          }
  1846.          case PNG_COLOR_TYPE_RGB_ALPHA:
  1847.          {
  1848.             if (row_info->bit_depth == 8)
  1849.             {
  1850. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1851.                if (gamma_to_1 && gamma_from_1 && gamma_table)
  1852.                {
  1853.                   for (i = 0, sp = row,
  1854.                      dp = row;
  1855.                      i < row_info->width; i++, sp += 4, dp += 3)
  1856.                   {
  1857.                      png_uint_16 a;
  1858.  
  1859.                      a = *(sp + 3);
  1860.                      if (a == 0xff)
  1861.                      {
  1862.                         *dp = gamma_table[*sp];
  1863.                         *(dp + 1) = gamma_table[*(sp + 1)];
  1864.                         *(dp + 2) = gamma_table[*(sp + 2)];
  1865.                      }
  1866.                      else if (a == 0)
  1867.                      {
  1868.                         *dp = background->red;
  1869.                         *(dp + 1) = background->green;
  1870.                         *(dp + 2) = background->blue;
  1871.                      }
  1872.                      else
  1873.                      {
  1874.                         png_uint_16 v;
  1875.  
  1876.                         v = gamma_to_1[*sp];
  1877.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1878.                            (png_uint_16)background_1->red *
  1879.                            (255 - a) + 127) / 255);
  1880.                         *dp = gamma_from_1[v];
  1881.                         v = gamma_to_1[*(sp + 1)];
  1882.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1883.                            (png_uint_16)background_1->green *
  1884.                            (255 - a) + 127) / 255);
  1885.                         *(dp + 1) = gamma_from_1[v];
  1886.                         v = gamma_to_1[*(sp + 2)];
  1887.                         v = (png_uint_16)(((png_uint_16)(v) * a +
  1888.                            (png_uint_16)background_1->blue *
  1889.                            (255 - a) + 127) / 255);
  1890.                         *(dp + 2) = gamma_from_1[v];
  1891.                      }
  1892.                   }
  1893.                }
  1894.                else
  1895. #endif
  1896.                {
  1897.                   for (i = 0, sp = row,
  1898.                      dp = row;
  1899.                      i < row_info->width; i++, sp += 4, dp += 3)
  1900.                   {
  1901.                      png_uint_16 a;
  1902.  
  1903.                      a = *(sp + 3);
  1904.                      if (a == 0xff)
  1905.                      {
  1906.                         *dp = *sp;
  1907.                         *(dp + 1) = *(sp + 1);
  1908.                         *(dp + 2) = *(sp + 2);
  1909.                      }
  1910.                      else if (a == 0)
  1911.                      {
  1912.                         *dp = background->red;
  1913.                         *(dp + 1) = background->green;
  1914.                         *(dp + 2) = background->blue;
  1915.                      }
  1916.                      else
  1917.                      {
  1918.                         *dp = (png_byte)(((png_uint_16)(*sp) * a +
  1919.                            (png_uint_16)background->red *
  1920.                            (255 - a) + 127) / 255);
  1921.                         *(dp + 1) = (png_byte)(((png_uint_16)(*(sp + 1)) * a +
  1922.                            (png_uint_16)background->green *
  1923.                            (255 - a) + 127) / 255);
  1924.                         *(dp + 2) = (png_byte)(((png_uint_16)(*(sp + 2)) * a +
  1925.                            (png_uint_16)background->blue *
  1926.                            (255 - a) + 127) / 255);
  1927.                      }
  1928.                   }
  1929.                }
  1930.             }
  1931.             else if (row_info->bit_depth == 16)
  1932.             {
  1933. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1934.                if (gamma_16 && gamma_16_from_1 && gamma_16_to_1)
  1935.                {
  1936.                   for (i = 0, sp = row,
  1937.                      dp = row;
  1938.                      i < row_info->width; i++, sp += 8, dp += 6)
  1939.                   {
  1940.                      png_uint_16 a;
  1941.  
  1942.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  1943.                         (png_uint_16)(*(sp + 7)));
  1944.                      if (a == (png_uint_16)0xffff)
  1945.                      {
  1946.                         png_uint_16 v;
  1947.  
  1948.                         v = gamma_16[
  1949.                            *(sp + 1) >> gamma_shift][*sp];
  1950.                         *dp = (png_byte)((v >> 8) & 0xff);
  1951.                         *(dp + 1) = (png_byte)(v & 0xff);
  1952.                         v = gamma_16[
  1953.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1954.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1955.                         *(dp + 3) = (png_byte)(v & 0xff);
  1956.                         v = gamma_16[
  1957.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1958.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  1959.                         *(dp + 5) = (png_byte)(v & 0xff);
  1960.                      }
  1961.                      else if (a == 0)
  1962.                      {
  1963.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  1964.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  1965.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  1966.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  1967.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  1968.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  1969.                      }
  1970.                      else
  1971.                      {
  1972.                         png_uint_32 v;
  1973.  
  1974.                         v = gamma_16_to_1[
  1975.                            *(sp + 1) >> gamma_shift][*sp];
  1976.                         v = (v * (png_uint_32)a +
  1977.                            (png_uint_32)background->red *
  1978.                            (png_uint_32)((png_uint_16)65535L - a) +
  1979.                            (png_uint_16)32767) / (png_uint_16)65535L;
  1980.                         v = gamma_16_from_1[(size_t)(
  1981.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1982.                         *dp = (png_byte)((v >> 8) & 0xff);
  1983.                         *(dp + 1) = (png_byte)(v & 0xff);
  1984.                         v = gamma_16_to_1[
  1985.                            *(sp + 3) >> gamma_shift][*(sp + 2)];
  1986.                         v = (v * (png_uint_32)a +
  1987.                            (png_uint_32)background->green *
  1988.                            (png_uint_32)((png_uint_16)65535L - a) +
  1989.                            (png_uint_16)32767) / (png_uint_16)65535L;
  1990.                         v = gamma_16_from_1[(size_t)(
  1991.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  1992.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  1993.                         *(dp + 3) = (png_byte)(v & 0xff);
  1994.                         v = gamma_16_to_1[
  1995.                            *(sp + 5) >> gamma_shift][*(sp + 4)];
  1996.                         v = (v * (png_uint_32)a +
  1997.                            (png_uint_32)background->blue *
  1998.                            (png_uint_32)((png_uint_16)65535L - a) +
  1999.                            (png_uint_16)32767) / (png_uint_16)65535L;
  2000.                         v = gamma_16_from_1[(size_t)(
  2001.                            (v & 0xff) >> gamma_shift)][(size_t)(v >> 8)];
  2002.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2003.                         *(dp + 5) = (png_byte)(v & 0xff);
  2004.                      }
  2005.                   }
  2006.                }
  2007.                else
  2008. #endif
  2009.                {
  2010.                   for (i = 0, sp = row,
  2011.                      dp = row;
  2012.                      i < row_info->width; i++, sp += 8, dp += 6)
  2013.                   {
  2014.                      png_uint_16 a;
  2015.  
  2016.                      a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
  2017.                         (png_uint_16)(*(sp + 7)));
  2018.                      if (a == (png_uint_16)0xffff)
  2019.                      {
  2020.                         png_memcpy(dp, sp, 6);
  2021.                      }
  2022.                      else if (a == 0)
  2023.                      {
  2024.                         *dp = (png_byte)((background->red >> 8) & 0xff);
  2025.                         *(dp + 1) = (png_byte)(background->red & 0xff);
  2026.                         *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2027.                         *(dp + 3) = (png_byte)(background->green & 0xff);
  2028.                         *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2029.                         *(dp + 5) = (png_byte)(background->blue & 0xff);
  2030.                      }
  2031.                      else
  2032.                      {
  2033.                         png_uint_32 r, g, b, v;
  2034.  
  2035.                         r = ((png_uint_32)(*sp) << 8) +
  2036.                            (png_uint_32)(*(sp + 1));
  2037.                         g = ((png_uint_32)(*(sp + 2)) << 8) +
  2038.                            (png_uint_32)(*(sp + 3));
  2039.                         b = ((png_uint_32)(*(sp + 4)) << 8) +
  2040.                            (png_uint_32)(*(sp + 5));
  2041.                         v = (r * (png_uint_32)a +
  2042.                            (png_uint_32)background->red *
  2043.                            (png_uint_32)((png_uint_32)65535L - a) +
  2044.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2045.                         *dp = (png_byte)((v >> 8) & 0xff);
  2046.                         *(dp + 1) = (png_byte)(v & 0xff);
  2047.                         v = (g * (png_uint_32)a +
  2048.                            (png_uint_32)background->green *
  2049.                            (png_uint_32)((png_uint_32)65535L - a) +
  2050.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2051.                         *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  2052.                         *(dp + 3) = (png_byte)(v & 0xff);
  2053.                         v = (b * (png_uint_32)a +
  2054.                            (png_uint_32)background->blue *
  2055.                            (png_uint_32)((png_uint_32)65535L - a) +
  2056.                            (png_uint_32)32767) / (png_uint_32)65535L;
  2057.                         *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  2058.                         *(dp + 5) = (png_byte)(v & 0xff);
  2059.                      }
  2060.                   }
  2061.                }
  2062.             }
  2063.             break;
  2064.          }
  2065.       }
  2066.  
  2067.       if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  2068.       {
  2069.          row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  2070.          row_info->channels--;
  2071.          row_info->pixel_depth = (png_byte)(row_info->channels *
  2072.             row_info->bit_depth);
  2073.          row_info->rowbytes = ((row_info->width *
  2074.             row_info->pixel_depth + 7) >> 3);
  2075.       }
  2076.    }
  2077. }
  2078. #endif
  2079.  
  2080. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2081. /* gamma correct the image, avoiding the alpha channel.  Make sure
  2082.    you do this after you deal with the trasparency issue on grayscale
  2083.    or rgb images. If your bit depth is 8, use gamma_table, if it is 16,
  2084.    use gamma_16_table and gamma_shift.  Build these with
  2085.    build_gamma_table().  If your bit depth <= 8, gamma correct a
  2086.    palette, not the data.  */
  2087. void
  2088. png_do_gamma(png_row_infop row_info, png_bytep row,
  2089.    png_bytep gamma_table, png_uint_16pp gamma_16_table,
  2090.    int gamma_shift)
  2091. {
  2092.    png_bytep sp;
  2093.    png_uint_32 i;
  2094.  
  2095.    if (row && row_info && ((row_info->bit_depth <= 8 && gamma_table) ||
  2096.       (row_info->bit_depth == 16 && gamma_16_table)))
  2097.    {
  2098.       switch (row_info->color_type)
  2099.       {
  2100.          case PNG_COLOR_TYPE_RGB:
  2101.          {
  2102.             if (row_info->bit_depth == 8)
  2103.             {
  2104.                for (i = 0, sp = row;
  2105.                   i < row_info->width; i++)
  2106.                {
  2107.                   *sp = gamma_table[*sp];
  2108.                   sp++;
  2109.                   *sp = gamma_table[*sp];
  2110.                   sp++;
  2111.                   *sp = gamma_table[*sp];
  2112.                   sp++;
  2113.                }
  2114.             }
  2115.             else if (row_info->bit_depth == 16)
  2116.             {
  2117.                for (i = 0, sp = row;
  2118.                   i < row_info->width; i++)
  2119.                {
  2120.                   png_uint_16 v;
  2121.  
  2122.                   v = gamma_16_table[*(sp + 1) >>
  2123.                      gamma_shift][*sp];
  2124.                   *sp = (png_byte)((v >> 8) & 0xff);
  2125.                   *(sp + 1) = (png_byte)(v & 0xff);
  2126.                   sp += 2;
  2127.                   v = gamma_16_table[*(sp + 1) >>
  2128.                      gamma_shift][*sp];
  2129.                   *sp = (png_byte)((v >> 8) & 0xff);
  2130.                   *(sp + 1) = (png_byte)(v & 0xff);
  2131.                   sp += 2;
  2132.                   v = gamma_16_table[*(sp + 1) >>
  2133.                      gamma_shift][*sp];
  2134.                   *sp = (png_byte)((v >> 8) & 0xff);
  2135.                   *(sp + 1) = (png_byte)(v & 0xff);
  2136.                   sp += 2;
  2137.                }
  2138.             }
  2139.             break;
  2140.          }
  2141.          case PNG_COLOR_TYPE_RGB_ALPHA:
  2142.          {
  2143.             if (row_info->bit_depth == 8)
  2144.             {
  2145.                for (i = 0, sp = row;
  2146.                   i < row_info->width; i++)
  2147.                {
  2148.                   *sp = gamma_table[*sp];
  2149.                   sp++;
  2150.                   *sp = gamma_table[*sp];
  2151.                   sp++;
  2152.                   *sp = gamma_table[*sp];
  2153.                   sp++;
  2154.                   sp++;
  2155.                }
  2156.             }
  2157.             else if (row_info->bit_depth == 16)
  2158.             {
  2159.                for (i = 0, sp = row;
  2160.                   i < row_info->width; i++)
  2161.                {
  2162.                   png_uint_16 v;
  2163.  
  2164.                   v = gamma_16_table[*(sp + 1) >>
  2165.                      gamma_shift][*sp];
  2166.                   *sp = (png_byte)((v >> 8) & 0xff);
  2167.                   *(sp + 1) = (png_byte)(v & 0xff);
  2168.                   sp += 2;
  2169.                   v = gamma_16_table[*(sp + 1) >>
  2170.                      gamma_shift][*sp];
  2171.                   *sp = (png_byte)((v >> 8) & 0xff);
  2172.                   *(sp + 1) = (png_byte)(v & 0xff);
  2173.                   sp += 2;
  2174.                   v = gamma_16_table[*(sp + 1) >>
  2175.                      gamma_shift][*sp];
  2176.                   *sp = (png_byte)((v >> 8) & 0xff);
  2177.                   *(sp + 1) = (png_byte)(v & 0xff);
  2178.                   sp += 4;
  2179.                }
  2180.             }
  2181.             break;
  2182.          }
  2183.          case PNG_COLOR_TYPE_GRAY_ALPHA:
  2184.          {
  2185.             if (row_info->bit_depth == 8)
  2186.             {
  2187.                for (i = 0, sp = row;
  2188.                   i < row_info->width; i++)
  2189.                {
  2190.                   *sp = gamma_table[*sp];
  2191.                   sp++;
  2192.                   sp++;
  2193.                }
  2194.             }
  2195.             else if (row_info->bit_depth == 16)
  2196.             {
  2197.                for (i = 0, sp = row;
  2198.                   i < row_info->width; i++)
  2199.                {
  2200.                   png_uint_16 v;
  2201.  
  2202.                   v = gamma_16_table[*(sp + 1) >>
  2203.                      gamma_shift][*sp];
  2204.                   *sp = (png_byte)((v >> 8) & 0xff);
  2205.                   *(sp + 1) = (png_byte)(v & 0xff);
  2206.                   sp += 4;
  2207.                }
  2208.             }
  2209.             break;
  2210.          }
  2211.          case PNG_COLOR_TYPE_GRAY:
  2212.          {
  2213.             if (row_info->bit_depth == 8)
  2214.             {
  2215.                for (i = 0, sp = row;
  2216.                   i < row_info->width; i++)
  2217.                {
  2218.                   *sp = gamma_table[*sp];
  2219.                   sp++;
  2220.                }
  2221.             }
  2222.             else if (row_info->bit_depth == 16)
  2223.             {
  2224.                for (i = 0, sp = row;
  2225.                   i < row_info->width; i++)
  2226.                {
  2227.                   png_uint_16 v;
  2228.  
  2229.                   v = gamma_16_table[*(sp + 1) >>
  2230.                      gamma_shift][*sp];
  2231.                   *sp = (png_byte)((v >> 8) & 0xff);
  2232.                   *(sp + 1) = (png_byte)(v & 0xff);
  2233.                   sp += 2;
  2234.                }
  2235.             }
  2236.             break;
  2237.          }
  2238.       }
  2239.    }
  2240. }
  2241. #endif
  2242.  
  2243. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2244. /* expands a palette row to an rgb or rgba row depending
  2245.    upon whether you supply trans and num_trans */
  2246. void
  2247. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  2248.    png_colorp palette,
  2249.    png_bytep trans, int num_trans)
  2250. {
  2251.    int shift, value;
  2252.    png_bytep sp, dp;
  2253.    png_uint_32 i;
  2254.  
  2255.    if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  2256.    {
  2257.       if (row_info->bit_depth < 8)
  2258.       {
  2259.          switch (row_info->bit_depth)
  2260.          {
  2261.             case 1:
  2262.             {
  2263.                sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2264.                dp = row + (png_size_t)row_info->width - 1;
  2265.                shift = 7 - (int)((row_info->width + 7) & 7);
  2266.                for (i = 0; i < row_info->width; i++)
  2267.                {
  2268.                   if ((*sp >> shift) & 0x1)
  2269.                      *dp = 1;
  2270.                   else
  2271.                      *dp = 0;
  2272.                   if (shift == 7)
  2273.                   {
  2274.                      shift = 0;
  2275.                      sp--;
  2276.                   }
  2277.                   else
  2278.                      shift++;
  2279.  
  2280.                   dp--;
  2281.                }
  2282.                break;
  2283.             }
  2284.             case 2:
  2285.             {
  2286.                sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2287.                dp = row + (png_size_t)row_info->width - 1;
  2288.                shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2289.                for (i = 0; i < row_info->width; i++)
  2290.                {
  2291.                   value = (*sp >> shift) & 0x3;
  2292.                   *dp = (png_byte)value;
  2293.                   if (shift == 6)
  2294.                   {
  2295.                      shift = 0;
  2296.                      sp--;
  2297.                   }
  2298.                   else
  2299.                      shift += 2;
  2300.  
  2301.                   dp--;
  2302.                }
  2303.                break;
  2304.             }
  2305.             case 4:
  2306.             {
  2307.                sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2308.                dp = row + (png_size_t)row_info->width - 1;
  2309.                shift = (int)((row_info->width & 1) << 2);
  2310.                for (i = 0; i < row_info->width; i++)
  2311.                {
  2312.                   value = (*sp >> shift) & 0xf;
  2313.                   *dp = (png_byte)value;
  2314.                   if (shift == 4)
  2315.                   {
  2316.                      shift = 0;
  2317.                      sp--;
  2318.                   }
  2319.                   else
  2320.                      shift += 4;
  2321.  
  2322.                   dp--;
  2323.                }
  2324.                break;
  2325.             }
  2326.          }
  2327.          row_info->bit_depth = 8;
  2328.          row_info->pixel_depth = 8;
  2329.          row_info->rowbytes = row_info->width;
  2330.       }
  2331.       switch (row_info->bit_depth)
  2332.       {
  2333.          case 8:
  2334.          {
  2335.             if (trans)
  2336.             {
  2337.                sp = row + (png_size_t)row_info->width - 1;
  2338.                dp = row + (png_size_t)(row_info->width << 2) - 1;
  2339.  
  2340.                for (i = 0; i < row_info->width; i++)
  2341.                {
  2342.                   if (*sp >= (png_byte)num_trans)
  2343.                      *dp-- = 0xff;
  2344.                   else
  2345.                      *dp-- = trans[*sp];
  2346.                   *dp-- = palette[*sp].blue;
  2347.                   *dp-- = palette[*sp].green;
  2348.                   *dp-- = palette[*sp].red;
  2349.                   sp--;
  2350.                }
  2351.                row_info->bit_depth = 8;
  2352.                row_info->pixel_depth = 32;
  2353.                row_info->rowbytes = row_info->width * 4;
  2354.                row_info->color_type = 6;
  2355.                row_info->channels = 4;
  2356.             }
  2357.             else
  2358.             {
  2359.                sp = row + (png_size_t)row_info->width - 1;
  2360.                dp = row + (png_size_t)(row_info->width * 3) - 1;
  2361.  
  2362.                for (i = 0; i < row_info->width; i++)
  2363.                {
  2364.                   *dp-- = palette[*sp].blue;
  2365.                   *dp-- = palette[*sp].green;
  2366.                   *dp-- = palette[*sp].red;
  2367.                   sp--;
  2368.                }
  2369.                row_info->bit_depth = 8;
  2370.                row_info->pixel_depth = 24;
  2371.                row_info->rowbytes = row_info->width * 3;
  2372.                row_info->color_type = 2;
  2373.                row_info->channels = 3;
  2374.             }
  2375.             break;
  2376.          }
  2377.       }
  2378.    }
  2379. }
  2380.  
  2381. /* if the bit depth < 8, it is expanded to 8.  Also, if the
  2382.    transparency value is supplied, an alpha channel is built. */
  2383. void
  2384. png_do_expand(png_row_infop row_info, png_bytep row,
  2385.    png_color_16p trans_value)
  2386. {
  2387.    int shift, value;
  2388.    png_bytep sp, dp;
  2389.    png_uint_32 i;
  2390.  
  2391.    if (row && row_info)
  2392.    {
  2393.       if (row_info->color_type == PNG_COLOR_TYPE_GRAY )
  2394.       {
  2395.          png_uint_16 gray = trans_value ? trans_value->gray : 0;
  2396.  
  2397.          if (row_info->bit_depth < 8)
  2398.          {
  2399.             switch (row_info->bit_depth)
  2400.             {
  2401.                case 1:
  2402.                {
  2403.                   gray *= 0xff;
  2404.                   sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2405.                   dp = row + (png_size_t)row_info->width - 1;
  2406.                   shift = 7 - (int)((row_info->width + 7) & 7);
  2407.                   for (i = 0; i < row_info->width; i++)
  2408.                   {
  2409.                      if ((*sp >> shift) & 0x1)
  2410.                         *dp = 0xff;
  2411.                      else
  2412.                         *dp = 0;
  2413.                      if (shift == 7)
  2414.                      {
  2415.                         shift = 0;
  2416.                         sp--;
  2417.                      }
  2418.                      else
  2419.                         shift++;
  2420.  
  2421.                      dp--;
  2422.                   }
  2423.                   break;
  2424.                }
  2425.                case 2:
  2426.                {
  2427.                   gray *= 0x55;
  2428.                   sp = row + (png_size_t)((row_info->width - 1) >> 2);
  2429.                   dp = row + (png_size_t)row_info->width - 1;
  2430.                   shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
  2431.                   for (i = 0; i < row_info->width; i++)
  2432.                   {
  2433.                      value = (*sp >> shift) & 0x3;
  2434.                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
  2435.                         (value << 6));
  2436.                      if (shift == 6)
  2437.                      {
  2438.                         shift = 0;
  2439.                         sp--;
  2440.                      }
  2441.                      else
  2442.                         shift += 2;
  2443.  
  2444.                      dp--;
  2445.                   }
  2446.                   break;
  2447.                }
  2448.                case 4:
  2449.                {
  2450.                   gray *= 0x11;
  2451.                   sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2452.                   dp = row + (png_size_t)row_info->width - 1;
  2453.                   shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
  2454.                   for (i = 0; i < row_info->width; i++)
  2455.                   {
  2456.                      value = (*sp >> shift) & 0xf;
  2457.                      *dp = (png_byte)(value | (value << 4));
  2458.                      if (shift == 4)
  2459.                      {
  2460.                         shift = 0;
  2461.                         sp--;
  2462.                      }
  2463.                      else
  2464.                         shift = 4;
  2465.  
  2466.                      dp--;
  2467.                   }
  2468.                   break;
  2469.                }
  2470.             }
  2471.             row_info->bit_depth = 8;
  2472.             row_info->pixel_depth = 8;
  2473.             row_info->rowbytes = row_info->width;
  2474.          }
  2475.  
  2476.          if (trans_value)
  2477.          {
  2478.             if (row_info->bit_depth == 8)
  2479.             {
  2480.                sp = row + (png_size_t)row_info->width - 1;
  2481.                dp = row + (png_size_t)(row_info->width << 1) - 1;
  2482.                for (i = 0; i < row_info->width; i++)
  2483.                {
  2484.                   if (*sp == gray)
  2485.                      *dp-- = 0;
  2486.                   else
  2487.                      *dp-- = 0xff;
  2488.                   *dp-- = *sp--;
  2489.                }
  2490.             }
  2491.             else if (row_info->bit_depth == 16)
  2492.             {
  2493.                sp = row + (png_size_t)row_info->rowbytes - 1;
  2494.                dp = row + (png_size_t)(row_info->rowbytes << 1) - 1;
  2495.                for (i = 0; i < row_info->width; i++)
  2496.                {
  2497.                   if (((png_uint_16)*(sp) |
  2498.                      ((png_uint_16)*(sp - 1) << 8)) == gray)
  2499.                   {
  2500.                      *dp-- = 0;
  2501.                      *dp-- = 0;
  2502.                   }
  2503.                   else
  2504.                   {
  2505.                      *dp-- = 0xff;
  2506.                      *dp-- = 0xff;
  2507.                   }
  2508.                   *dp-- = *sp--;
  2509.                   *dp-- = *sp--;
  2510.                }
  2511.             }
  2512.             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  2513.             row_info->channels = 2;
  2514.             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  2515.             row_info->rowbytes =
  2516.                ((row_info->width * row_info->pixel_depth) >> 3);
  2517.          }
  2518.       }
  2519.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  2520.       {
  2521.          if (row_info->bit_depth == 8)
  2522.          {
  2523.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2524.             dp = row + (png_size_t)(row_info->width << 2) - 1;
  2525.             for (i = 0; i < row_info->width; i++)
  2526.             {
  2527.                if (*(sp - 2) == trans_value->red &&
  2528.                   *(sp - 1) == trans_value->green &&
  2529.                   *(sp - 0) == trans_value->blue)
  2530.                   *dp-- = 0;
  2531.                else
  2532.                   *dp-- = 0xff;
  2533.                *dp-- = *sp--;
  2534.                *dp-- = *sp--;
  2535.                *dp-- = *sp--;
  2536.             }
  2537.          }
  2538.          else if (row_info->bit_depth == 16)
  2539.          {
  2540.             sp = row + (png_size_t)row_info->rowbytes - 1;
  2541.             dp = row + (png_size_t)(row_info->width << 3) - 1;
  2542.             for (i = 0; i < row_info->width; i++)
  2543.             {
  2544.                if ((((png_uint_16)*(sp - 4) |
  2545.                   ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
  2546.                   (((png_uint_16)*(sp - 2) |
  2547.                   ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
  2548.                   (((png_uint_16)*(sp - 0) |
  2549.                   ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
  2550.                {
  2551.                   *dp-- = 0;
  2552.                   *dp-- = 0;
  2553.                }
  2554.                else
  2555.                {
  2556.                   *dp-- = 0xff;
  2557.                   *dp-- = 0xff;
  2558.                }
  2559.                *dp-- = *sp--;
  2560.                *dp-- = *sp--;
  2561.                *dp-- = *sp--;
  2562.                *dp-- = *sp--;
  2563.                *dp-- = *sp--;
  2564.                *dp-- = *sp--;
  2565.             }
  2566.          }
  2567.          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  2568.          row_info->channels = 4;
  2569.          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  2570.          row_info->rowbytes =
  2571.             ((row_info->width * row_info->pixel_depth) >> 3);
  2572.       }
  2573.    }
  2574. }
  2575. #endif
  2576.  
  2577. #if defined(PNG_READ_DITHER_SUPPORTED)
  2578. void
  2579. png_do_dither(png_row_infop row_info, png_bytep row,
  2580.     png_bytep palette_lookup, png_bytep dither_lookup)
  2581. {
  2582.    png_bytep sp, dp;
  2583.    png_uint_32 i;
  2584.  
  2585.    if (row && row_info)
  2586.    {
  2587.       if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  2588.          palette_lookup && row_info->bit_depth == 8)
  2589.       {
  2590.          int r, g, b, p;
  2591.          sp = row;
  2592.          dp = row;
  2593.          for (i = 0; i < row_info->width; i++)
  2594.          {
  2595.             r = *sp++;
  2596.             g = *sp++;
  2597.             b = *sp++;
  2598.  
  2599.             /* this looks real messy, but the compiler will reduce
  2600.                it down to a reasonable formula.  For example, with
  2601.                5 bits per color, we get:
  2602.                p = (((r >> 3) & 0x1f) << 10) |
  2603.                   (((g >> 3) & 0x1f) << 5) |
  2604.                   ((b >> 3) & 0x1f);
  2605.                */
  2606.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2607.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2608.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2609.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2610.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2611.                (PNG_DITHER_BLUE_BITS)) |
  2612.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2613.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2614.  
  2615.             *dp++ = palette_lookup[p];
  2616.          }
  2617.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2618.          row_info->channels = 1;
  2619.          row_info->pixel_depth = row_info->bit_depth;
  2620.          row_info->rowbytes =
  2621.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2622.       }
  2623.       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  2624.          palette_lookup && row_info->bit_depth == 8)
  2625.       {
  2626.          int r, g, b, p;
  2627.          sp = row;
  2628.          dp = row;
  2629.          for (i = 0; i < row_info->width; i++)
  2630.          {
  2631.             r = *sp++;
  2632.             g = *sp++;
  2633.             b = *sp++;
  2634.             sp++;
  2635.  
  2636.             p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  2637.                ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  2638.                (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  2639.                (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  2640.                ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  2641.                (PNG_DITHER_BLUE_BITS)) |
  2642.                ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  2643.                ((1 << PNG_DITHER_BLUE_BITS) - 1));
  2644.  
  2645.             *dp++ = palette_lookup[p];
  2646.          }
  2647.          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  2648.          row_info->channels = 1;
  2649.          row_info->pixel_depth = row_info->bit_depth;
  2650.          row_info->rowbytes =
  2651.             ((row_info->width * row_info->pixel_depth + 7) >> 3);
  2652.       }
  2653.       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  2654.          dither_lookup && row_info->bit_depth == 8)
  2655.       {
  2656.          sp = row;
  2657.          for (i = 0; i < row_info->width; i++, sp++)
  2658.          {
  2659.             *sp = dither_lookup[*sp];
  2660.          }
  2661.       }
  2662.    }
  2663. }
  2664. #endif
  2665.  
  2666. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2667. static int png_gamma_shift[] =
  2668.    {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
  2669.  
  2670. void
  2671. png_build_gamma_table(png_structp png_ptr)
  2672. {
  2673.    if (png_ptr->bit_depth <= 8)
  2674.    {
  2675.       int i;
  2676.       double g;
  2677.  
  2678.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2679.  
  2680.       png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
  2681.          (png_uint_32)256);
  2682.  
  2683.       for (i = 0; i < 256; i++)
  2684.       {
  2685.          png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  2686.             g) * 255.0 + .5);
  2687.       }
  2688.  
  2689.       if (png_ptr->transformations & PNG_BACKGROUND)
  2690.       {
  2691.          g = 1.0 / (png_ptr->gamma);
  2692.  
  2693.          png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
  2694.             (png_uint_32)256);
  2695.  
  2696.          for (i = 0; i < 256; i++)
  2697.          {
  2698.             png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  2699.                g) * 255.0 + .5);
  2700.          }
  2701.  
  2702.          g = 1.0 / (png_ptr->display_gamma);
  2703.  
  2704.          png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
  2705.             (png_uint_32)256);
  2706.  
  2707.          for (i = 0; i < 256; i++)
  2708.          {
  2709.             png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  2710.                g) * 255.0 + .5);
  2711.          }
  2712.       }
  2713.    }
  2714.    else
  2715.    {
  2716.       double g;
  2717.       int i, j, shift, num;
  2718.       int sig_bit;
  2719.       png_uint_32 ig;
  2720.  
  2721.       if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  2722.       {
  2723.          sig_bit = (int)png_ptr->sig_bit.red;
  2724.          if ((int)png_ptr->sig_bit.green > sig_bit)
  2725.             sig_bit = png_ptr->sig_bit.green;
  2726.          if ((int)png_ptr->sig_bit.blue > sig_bit)
  2727.             sig_bit = png_ptr->sig_bit.blue;
  2728.       }
  2729.       else
  2730.       {
  2731.          sig_bit = (int)png_ptr->sig_bit.gray;
  2732.       }
  2733.  
  2734.       if (sig_bit > 0)
  2735.          shift = 16 - sig_bit;
  2736.       else
  2737.          shift = 0;
  2738.  
  2739.       if (png_ptr->transformations & PNG_16_TO_8)
  2740.       {
  2741.          if (shift < (16 - PNG_MAX_GAMMA_8))
  2742.             shift = (16 - PNG_MAX_GAMMA_8);
  2743.       }
  2744.  
  2745.       if (shift > 8)
  2746.          shift = 8;
  2747.       if (shift < 0)
  2748.          shift = 0;
  2749.  
  2750.       png_ptr->gamma_shift = (png_byte)shift;
  2751.  
  2752.       num = (1 << (8 - shift));
  2753.  
  2754.       g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma);
  2755.  
  2756.       png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
  2757.          num * sizeof (png_uint_16p ));
  2758.  
  2759.       if ((png_ptr->transformations & PNG_16_TO_8) &&
  2760.          !(png_ptr->transformations & PNG_BACKGROUND))
  2761.       {
  2762.          double fin, fout;
  2763.          png_uint_32 last, max;
  2764.  
  2765.          for (i = 0; i < num; i++)
  2766.          {
  2767.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  2768.                256 * sizeof (png_uint_16));
  2769.          }
  2770.  
  2771.          g = 1.0 / g;
  2772.          last = 0;
  2773.          for (i = 0; i < 256; i++)
  2774.          {
  2775.             fout = ((double)i + 0.5) / 256.0;
  2776.             fin = pow(fout, g);
  2777.             max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  2778.             while (last <= max)
  2779.             {
  2780.                png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2781.                   [(int)(last >> (8 - shift))] = (png_uint_16)(
  2782.                   (png_uint_16)i | ((png_uint_16)i << 8));
  2783.                last++;
  2784.             }
  2785.          }
  2786.          while (last < ((png_uint_32)num << 8))
  2787.          {
  2788.             png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  2789.                [(int)(last >> (8 - shift))] =
  2790.                (png_uint_16)65535L;
  2791.             last++;
  2792.          }
  2793.       }
  2794.       else
  2795.       {
  2796.          for (i = 0; i < num; i++)
  2797.          {
  2798.             png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  2799.                256 * sizeof (png_uint_16));
  2800.  
  2801.             ig = (((png_uint_32)i *
  2802.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2803.             for (j = 0; j < 256; j++)
  2804.             {
  2805.                png_ptr->gamma_16_table[i][j] =
  2806.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2807.                      65535.0, g) * 65535.0 + .5);
  2808.             }
  2809.          }
  2810.       }
  2811.  
  2812.       if (png_ptr->transformations & PNG_BACKGROUND)
  2813.       {
  2814.          g = 1.0 / (png_ptr->gamma);
  2815.  
  2816.          png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
  2817.             num * sizeof (png_uint_16p ));
  2818.  
  2819.          for (i = 0; i < num; i++)
  2820.          {
  2821.             png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
  2822.                256 * sizeof (png_uint_16));
  2823.  
  2824.             ig = (((png_uint_32)i *
  2825.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2826.             for (j = 0; j < 256; j++)
  2827.             {
  2828.                png_ptr->gamma_16_to_1[i][j] =
  2829.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2830.                      65535.0, g) * 65535.0 + .5);
  2831.             }
  2832.          }
  2833.          g = 1.0 / (png_ptr->display_gamma);
  2834.  
  2835.          png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
  2836.             num * sizeof (png_uint_16p));
  2837.  
  2838.          for (i = 0; i < num; i++)
  2839.          {
  2840.             png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
  2841.                256 * sizeof (png_uint_16));
  2842.  
  2843.             ig = (((png_uint_32)i *
  2844.                (png_uint_32)png_gamma_shift[shift]) >> 4);
  2845.             for (j = 0; j < 256; j++)
  2846.             {
  2847.                png_ptr->gamma_16_from_1[i][j] =
  2848.                   (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  2849.                      65535.0, g) * 65535.0 + .5);
  2850.             }
  2851.          }
  2852.       }
  2853.    }
  2854. }
  2855. #endif
  2856.  
  2857.